#!/bin/bash
# generate_config.sh - 本地生成 Dumbo 配置文件和阈值签名密钥

set -e

# ============================================
# 默认配置（可在环境变量中覆盖）
# ============================================
NODE_COUNT="${NODE_COUNT:-4}"              # 默认节点数
BATCH_SIZE="${BATCH_SIZE:-100}"            # 默认批次大小

# ============================================
# 从环境变量读取（必填）
# ============================================
IP_LIST="${IP_LIST:?必须设置 IP_LIST (形如 ip1,ip2,ip3)}"
HOST_LIST="${HOST_LIST:-}"                 # HOST_LIST 为可选，格式：user@ip1,user@ip2,...

# ============================================
# 其他配置
# ============================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="${SCRIPT_DIR%/*}"
CONFIG_GEN_DIR="${PROJECT_ROOT}/config_gen"
P2P_PORT_BASE="${P2P_PORT_BASE:-9000}"

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# 打印函数
print_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

print_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 显示用法
usage() {
    cat << EOF
用法: $0 [选项]

选项:
  -h, --help         显示此帮助信息
  -p, --port-base    P2P端口起始值（默认: 9000，可通过环境变量 P2P_PORT_BASE 设置）
  -d, --dir          config_gen目录路径（默认: $PROJECT_ROOT/config_gen）
  --git-push         生成后自动提交并推送到 Git（需要先配置 Git 仓库）
  --no-verify        不验证生成的配置文件

环境变量（必填）:
  IP_LIST            节点IP列表，逗号分隔（例如: "ip1,ip2,ip3,ip4"）

环境变量（可选）:
  NODE_COUNT         节点数（默认: 4）
  BATCH_SIZE         批次大小（默认: 100）
  HOST_LIST          主机列表，格式：user@ip1,user@ip2,...（可选）
  P2P_PORT_BASE      P2P端口起始值（默认: 9000）

示例:
  export IP_LIST="98.80.84.148,44.241.66.49,13.202.21.116,54.170.130.76"
  export HOST_LIST="ubuntu@98.80.84.148,ubuntu@44.241.66.49,ubuntu@13.202.21.116,ubuntu@54.170.130.76"
  export NODE_COUNT=4
  export BATCH_SIZE=100
  $0

  # 使用默认配置（NODE_COUNT=4, BATCH_SIZE=100）
  export IP_LIST="98.80.84.148,44.241.66.49,13.202.21.116,54.170.130.76"
  $0 --git-push
EOF
    exit 1
}

# 解析命令行参数
GIT_PUSH=false
VERIFY=true

while [[ $# -gt 0 ]]; do
    case $1 in
        -h|--help)
            usage
            ;;
        -p|--port-base)
            P2P_PORT_BASE="$2"
            shift 2
            ;;
        -d|--dir)
            CONFIG_GEN_DIR="$2"
            shift 2
            ;;
        --git-push)
            GIT_PUSH=true
            shift
            ;;
        --no-verify)
            VERIFY=false
            shift
            ;;
        -*)
            print_error "未知选项: $1"
            usage
            ;;
        *)
            print_error "未知参数: $1"
            usage
            ;;
    esac
done

# 验证项目目录
if [[ ! -d "$PROJECT_ROOT" ]]; then
    print_error "项目根目录不存在: $PROJECT_ROOT"
    exit 1
fi

# 验证 config_gen 目录
if [[ ! -d "$CONFIG_GEN_DIR" ]]; then
    print_warn "config_gen 目录不存在，正在创建: $CONFIG_GEN_DIR"
    mkdir -p "$CONFIG_GEN_DIR"
fi

# 验证 main.go 是否存在
if [[ ! -f "$CONFIG_GEN_DIR/main.go" ]]; then
    print_error "配置生成器不存在: $CONFIG_GEN_DIR/main.go"
    exit 1
fi

# 解析IP列表
IFS=',' read -ra IPS <<< "$IP_LIST"
ACTUAL_IP_COUNT=${#IPS[@]}

# 验证 IP 数量与 NODE_COUNT 是否一致
if [[ $ACTUAL_IP_COUNT -ne $NODE_COUNT ]]; then
    print_warn "IP 数量($ACTUAL_IP_COUNT)与 NODE_COUNT($NODE_COUNT) 不一致，使用实际IP数量: $ACTUAL_IP_COUNT"
    NODE_COUNT=$ACTUAL_IP_COUNT
fi

if [[ $NODE_COUNT -lt 1 ]]; then
    print_error "至少需要一个节点IP地址"
    exit 1
fi

# 验证 HOST_LIST（如果提供）
if [[ -n "$HOST_LIST" ]]; then
    IFS=',' read -ra HOSTS <<< "$HOST_LIST"
    if [[ ${#HOSTS[@]} -ne $NODE_COUNT ]]; then
        print_warn "HOST_LIST 数量(${#HOSTS[@]})与 NODE_COUNT($NODE_COUNT) 不一致"
    fi
fi

print_info "========================================="
print_info "  Dumbo 配置文件生成器"
print_info "========================================="
print_info "节点数量:      $NODE_COUNT"
print_info "批次大小:      $BATCH_SIZE"
print_info "节点IP列表:    $IP_LIST"
if [[ -n "$HOST_LIST" ]]; then
    print_info "主机列表:      $HOST_LIST"
fi
print_info "P2P端口范围:   $P2P_PORT_BASE - $((P2P_PORT_BASE + NODE_COUNT - 1))"
print_info "输出目录:      $CONFIG_GEN_DIR"
print_info "========================================="
echo ""

# 检查 Go 环境
print_info "检查 Go 环境..."
if ! command -v go &> /dev/null; then
    print_error "未找到 Go 命令，请先安装 Go"
    exit 1
fi

GO_VERSION=$(go version)
print_info "Go 版本: $GO_VERSION"
echo ""

# 进入 config_gen 目录
cd "$CONFIG_GEN_DIR"

# 生成 config_temp.yaml
print_info "生成 config_temp.yaml..."
CONFIG_TEMP_FILE="$CONFIG_GEN_DIR/config_temp.yaml"

cat > "$CONFIG_TEMP_FILE" << EOF
ddos: true
id_ip:
EOF

# 添加节点IP
for i in "${!IPS[@]}"; do
    echo "  $i: ${IPS[$i]}" >> "$CONFIG_TEMP_FILE"
done

cat >> "$CONFIG_TEMP_FILE" << EOF
id_name:
EOF

# 添加节点名称
for i in "${!IPS[@]}"; do
    echo "  $i: node$i" >> "$CONFIG_TEMP_FILE"
done

cat >> "$CONFIG_TEMP_FILE" << EOF
id_p2p_port:
EOF

# 添加P2P端口
for i in "${!IPS[@]}"; do
    port=$((P2P_PORT_BASE + i))
    echo "  $i: $port" >> "$CONFIG_TEMP_FILE"
done

cat >> "$CONFIG_TEMP_FILE" << EOF
log_level: 1
max_payload_size: 1000
max_pool: 10
mock_latency: 10
timeout: 1000
tx_size: ${BATCH_SIZE}
wait_time: 3
EOF

print_info "✓ config_temp.yaml 已生成"
echo ""

# 运行配置生成器
print_info "运行配置生成器 (go run main.go)..."
if go run main.go; then
    print_info "✓ 配置生成器执行成功"
else
    print_error "配置生成器执行失败"
    exit 1
fi
echo ""

# 验证生成的配置文件
if [[ "$VERIFY" == "true" ]]; then
    print_info "验证生成的配置文件..."
    ALL_OK=true
    
    for i in "${!IPS[@]}"; do
        config_file="$CONFIG_GEN_DIR/node$i.yaml"
        if [[ -f "$config_file" ]]; then
            print_info "  ✓ node$i.yaml 已生成"
        else
            print_error "  ✗ node$i.yaml 未生成"
            ALL_OK=false
        fi
    done
    
    if [[ "$ALL_OK" == "true" ]]; then
        print_info "✓ 所有配置文件验证通过（共 $NODE_COUNT 个节点）"
    else
        print_error "部分配置文件缺失"
        exit 1
    fi
    echo ""
fi

# Git 提交和推送（可选）
if [[ "$GIT_PUSH" == "true" ]]; then
    print_info "准备提交配置文件到 Git..."
    
    cd "$PROJECT_ROOT"
    
    # 检查是否是 Git 仓库
    if ! git rev-parse --git-dir > /dev/null 2>&1; then
        print_warn "当前目录不是 Git 仓库，跳过 Git 操作"
    else
        # 检查是否有更改
        if git diff --quiet --exit-code "$CONFIG_GEN_DIR" 2>/dev/null && \
           git diff --cached --quiet --exit-code "$CONFIG_GEN_DIR" 2>/dev/null; then
            print_info "配置文件没有更改，无需提交"
        else
            # 添加配置文件
            git add "$CONFIG_GEN_DIR"/*.yaml "$CONFIG_GEN_DIR/config_temp.yaml" 2>/dev/null || true
            
            # 提交
            COMMIT_MSG="Update config files: $NODE_COUNT nodes, batch_size=$BATCH_SIZE ($(date +%Y-%m-%d\ %H:%M:%S))"
            if git commit -m "$COMMIT_MSG" 2>/dev/null; then
                print_info "✓ 配置文件已提交"
                
                # 推送到远程
                if git push 2>/dev/null; then
                    print_info "✓ 配置文件已推送到远程仓库"
                else
                    print_warn "Git push 失败，请手动推送"
                fi
            else
                print_warn "Git commit 失败，可能没有更改需要提交"
            fi
        fi
    fi
    echo ""
fi

# 完成
print_info "========================================="
print_info "  配置文件生成完成！"
print_info "========================================="
print_info "配置文件位置: $CONFIG_GEN_DIR/"
print_info "生成的文件:"
for i in "${!IPS[@]}"; do
    print_info "  - node$i.yaml"
done
print_info ""
print_info "配置信息:"
print_info "  - 节点数: $NODE_COUNT"
print_info "  - 批次大小: $BATCH_SIZE"
print_info ""
print_info "下一步："
if [[ "$GIT_PUSH" != "true" ]]; then
    print_info "  1. 手动提交配置文件到 Git 仓库"
    print_info "     cd $PROJECT_ROOT"
    print_info "     git add config_gen/*.yaml"
    print_info "     git commit -m 'Update config files'"
    print_info "     git push"
    print_info ""
fi
print_info "  2. 远程节点从 Gitee 拉取代码时会自动获取配置文件"
print_info "  3. 运行 bushu.sh 进行部署"
print_info ""